package com.zhaopin.springboot.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhaopin.springboot.config.RestMock;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yin.peide
 * @date 2021-06-01 10:19
 * args[0] 是文件路径名
 */

@Service
public class VectorMain {

    @Autowired
    QuzmlService QuzmlService;


    public List getWordList(String paramWord) throws IOException {

        String retStr = QuzmlService.getString(paramWord);
        JSONObject jsonObjectxx = JSONObject.parseObject(retStr);
        JSONArray jsonArray11 = jsonObjectxx.getJSONObject("data").getJSONObject("analysis").getJSONArray("keywords");
        JSONArray jsonArray = jsonArray11.getJSONObject(0).getJSONObject("semantic").getJSONArray("split");

        int m = 0;
        int n = 0;
        m = jsonArray.size();

        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
            JSONArray jsonArray1 = jsonObject.getJSONArray("classfications");
            n = Math.max(jsonArray1.size(), n);
        }
        String[][] strAtrr = new String[m][n];

        for (int i = 0; i < strAtrr.length; i++) {
            for (int j = 0; j < strAtrr[i].length; j++) {

            }
        }

        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
            String word = jsonObject.getString("word");
            JSONArray jsonArray1 = jsonObject.getJSONArray("classfications");
            for (int i1 = 0; i1 < jsonArray1.size(); i1++) {
                JSONObject jsonObject1 = (JSONObject) jsonArray1.get(i1);
                String classfication = jsonObject1.getString("classfication");
                strAtrr[i][i1] = word + ":" + classfication;
            }
        }

        System.out.println("生成的数组是：");
        for (int i = 0; i < strAtrr.length; i++) {
            for (int j = 0; j < strAtrr[i].length; j++) {
                if (Objects.nonNull(strAtrr[i][j])) {
                    System.out.print(strAtrr[i][j] + " ");
                }

            }
            System.out.println();
        }

        System.out.println("-----------------------------------------------------------------------------");
//        String[][] strAtrr = new String[3][3];
//        String[] strA1 = {"销售:职位", "销售:职位方向"};
//        String[] strA2 = {"经理:职级", "经理:职位", "经理:技能"};
//        String[] strA3 = {"工程师:技能", "工程师:职级"};

//        String[] strA1 = {"销售:职位", "销售:职位方向"};
//        String[] strA2 = {"经理:职级", "经理:职位",null};
//        String[] strA3 = {"工程师:技能", "工程师:职级", "工程师:大师级"};
//
//        strAtrr[0] = strA1;
//        strAtrr[1] = strA2;
//        strAtrr[2] = strA3;


        TreeNode<String> treeNodeRoot = Solution.getTreeNode(strAtrr);


        List<String> list = Solution.breadthTraversal(treeNodeRoot);

        List<String> listStack = Solution.depthFirstTraversal(treeNodeRoot);

//        System.out.println("队列结果：");
        for (String s : list) {
//            System.out.println(s);
        }

//        System.out.println("栈结果：");
        for (String s : listStack) {
//            System.out.println(s);
        }

//        System.out.println("递归遍历:");
        Solution.depthOrderTraversalWithRecursive(treeNodeRoot);

//        System.out.println("层级是：" + Solution.resuleCentji(treeNodeRoot));


//        System.out.println("所有路径是：");
        Solution solution = new Solution();
        solution.init();
        List<String> allPathList = solution.listAllPathByRecursion(treeNodeRoot);
        for (String s : allPathList) {
//            System.out.println(s);
        }

        //生成所有分词拼串后OR 的结果
        List<String> listSplit = new ArrayList<>();

        System.out.println("生成solr的结果是：");
        allPathList.forEach(t -> {
            String[] oneAttr = t.split(";");
            //所有的一种路径的查询语句的集合，其中如果有相同语义的之间关系为 OR ,否则一并为 AND
            String oneAttrQueryStr = Solution.getOneAttrQueryStrWithSpecial(oneAttr);
            System.out.println(t + "------------:" + oneAttrQueryStr);
            listSplit.add(oneAttrQueryStr);
        });

        return listSplit;
    }


}


class TreeNode<T> {

    private T value;
    private List<TreeNode> listTreeNode;

    public TreeNode(T value) {
        this.value = value;
    }

    public List<TreeNode> getListTreeNode() {
        return listTreeNode;
    }

    public void setListTreeNode(List<TreeNode> listTreeNode) {
        this.listTreeNode = listTreeNode;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "value=" + value +
                ", listTreeNode=" + listTreeNode +
                '}';
    }
}

class Solution {


    public void init() {
        this.pathList = new ArrayList<>();
    }

    private List<String> pathList;

    public List<String> getPathList() {
        return pathList;
    }

    public void setPathList(List<String> pathList) {
        this.pathList = pathList;
    }

    /**
     * 获取为树的结构
     *
     * @param strAtrr
     * @return
     */
    public static TreeNode<String> getTreeNode(String[][] strAtrr) {
        TreeNode<String> treeNodeRoot = new TreeNode<>("0");

        //n代表的是有多少个词
        int n = strAtrr.length;
        List<TreeNode> treeNodeListTheTemp = new ArrayList<>();
        for (int i = n - 1; i >= 0; i--) {
            //m 就是动态的    m 代表的是每行词的个数
            int m = strAtrr[i].length;
            for (int j = 0; j < m; j++) {

                List<TreeNode> treeNodesTheThree = new ArrayList<>();

                if (i < n - 1) {
                    if (Objects.nonNull(strAtrr[i][j])) {
                        TreeNode<String> treeNode = new TreeNode<>(strAtrr[i][j]);
                        treeNode.setListTreeNode(treeNodeListTheTemp);
                    }

                    for (int k = 0; k < strAtrr[i].length; k++) {
                        String str = strAtrr[i][k];
                        if (Objects.isNull(str)) {
                            continue;
                        }
                        TreeNode<String> treeNodeInner = new TreeNode<>(str);
                        treeNodeInner.setListTreeNode(treeNodeListTheTemp);
                        treeNodesTheThree.add(treeNodeInner);

                    }

                }
                //如果是最后一行
                if (i == n - 1) {
                    for (int k = 0; k < strAtrr[n - 1].length; k++) {
                        String str = strAtrr[n - 1][k];
                        if (Objects.isNull(str)) {
                            continue;
                        }
                        TreeNode<String> treeNode = new TreeNode<>(str);
                        //第一次循环这些就是最根的list
                        treeNodesTheThree.add(treeNode);

                    }
                }
                if (j == strAtrr[i].length - 1) {
                    treeNodeListTheTemp = treeNodesTheThree;
                    if (i == 0) {
                        treeNodeRoot.setListTreeNode(treeNodeListTheTemp);
                    }
                }


            }


        }
        return treeNodeRoot;
    }

    /**
     * 获取为mapji
     *
     * @param strAtrr
     * @return
     */
    public static Map getTreeMap(String[][] strAtrr) {
        //n 代表有三个词
        // 另外的一个三 是最多有多少个语义
        int n = 3;
        Map<String, TreeNode<String>> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < 3; j++) {
                if (j < strAtrr[i].length) {
                    List<TreeNode> listTreeNode = new ArrayList<>();

                    if (i + 1 < n) {
                        //设置ListTree
                        for (int i1 = 0; i1 < strAtrr[i + 1].length; i1++) {
                            String str = strAtrr[i + 1][i1];
                            TreeNode<String> treeNode = new TreeNode<>(str);
                            listTreeNode.add(treeNode);
                        }
                    }

                    TreeNode<String> treeNode = new TreeNode<>(strAtrr[i][j]);
                    treeNode.setListTreeNode(listTreeNode);

                    map.put(strAtrr[i][j], treeNode);
                }

            }
        }

        return null;
    }

    /**
     * 广度遍历
     *
     * @return
     */
    public static List<String> breadthTraversal(TreeNode<String> treeNode) {
        List<String> list = new ArrayList<String>();
        Queue<TreeNode<String>> queue = new LinkedList<>();

        if (null == treeNode.getListTreeNode()) {
            return list;
        }

        //先插入队列
        queue.offer(treeNode);

        while (!queue.isEmpty()) {
            TreeNode<String> tree = queue.poll();

            List<TreeNode> listInner = tree.getListTreeNode();
            if (Objects.nonNull(listInner)) {
                for (TreeNode node : listInner) {
                    queue.offer(node);
                }
            }


            list.add(tree.getValue());
        }
        return list;
    }

    /**
     * 深度遍历
     *
     * @return
     */
    public static List<String> depthFirstTraversal(TreeNode<String> treeNode) {
        List<String> list = new ArrayList<String>();
        Stack<TreeNode<String>> stack = new Stack<>();

        if (null == treeNode.getListTreeNode()) {
            return list;
        }

        stack.push(treeNode);

        while (!stack.isEmpty()) {
            TreeNode<String> tree = stack.pop();

            List<TreeNode> listInner = tree.getListTreeNode();
            if (Objects.nonNull(listInner)) {
                for (int i = listInner.size() - 1; i >= 0; i--) {
                    TreeNode<String> treeNodeInner = listInner.get(i);
                    stack.push(treeNodeInner);
                }
            }

            list.add(tree.getValue());
        }
        return list;
    }

    public static void depthOrderTraversalWithRecursive(TreeNode<String> treeNode) {
        depthTraversal(treeNode);
    }

    private static void depthTraversal(TreeNode<String> node) {
        List<TreeNode> list = node.getListTreeNode();
//        System.out.println(node.getValue() + "  ");
        if (list != null) {
            for (TreeNode treeNode : list) {
                depthTraversal(treeNode);
            }
        }
    }

    /**
     * 返回树的层级
     */
    public static int resuleCentji(TreeNode<String> treeNode) {
        return treeNode.getListTreeNode() == null ? 0 : resuleCentji(treeNode.getListTreeNode().get(0)) + 1;
    }

    /**
     * 最后一个牛逼终极版 展示所有树的路径
     */
    private void listPath(TreeNode<String> root, String path) {

        if (Objects.isNull(root.getListTreeNode())) {//叶子节点
            path = path + root.getValue();
            pathList.add(path); //将结果保存在list中
            return;
        } else { //非叶子节点
            path = path + root.getValue() + ";";

            //进行子节点的递归
            List<TreeNode> childs = root.getListTreeNode();
            Iterator iterator = childs.iterator();
            while (iterator.hasNext()) {
                TreeNode treeNode = (TreeNode) iterator.next();
                listPath(treeNode, path);
            }
        }
    }

    public List<String> listAllPathByRecursion(TreeNode<String> treeNode) {
        //清空路径容器
        this.pathList.clear();

        listPath(treeNode, "");
        return this.pathList;
    }


    public static String getOneAttrQueryStrWithSpecial(String[] oneAttr) {

        // 3  -> 职位;技能
        // 13 -> 城市;区域
        Map<String, String> specialFamily = new HashMap();
        specialFamily.put("3", "职位;技能");
        specialFamily.put("13", "城市;区域");
        List<String> list = new ArrayList<>();
        String andOperation = " AND ";
        String orOperation = " OR ";

        if (Objects.nonNull(oneAttr) && oneAttr.length > 1) {
            Map<String, String> sematicAndWordWithQueryStrMap = new HashMap<>();
            Set<String> sematicAndWordSet = new HashSet<>();
            for (int i = 1; i < oneAttr.length; i++) {
                //开始直接获取第二个元素，排除0节点这个根节点
                String wordWithsemantic = oneAttr[i];
                String oneQueryStr = wordWithsemantic + "->solr";
                sematicAndWordWithQueryStrMap.put(wordWithsemantic, oneQueryStr);
                sematicAndWordSet.add(wordWithsemantic);
            }

            Set<Set<String>> setCollection = new HashSet<>();

            for (Map.Entry<String, String> map : specialFamily.entrySet()) {
                String semanticMulit = map.getValue();
                String[] sAttr = semanticMulit.split(";");
                Set<String> setInner = new HashSet<>();
                for (int i = 0; i < sAttr.length; i++) {
                    //职位
                    for (String sematicStr : sematicAndWordSet) {
                        if (sematicStr.split(":")[1].equals(sAttr[i])) {
                            setInner.add(sematicStr);
                        }
                    }
                }
                setCollection.add(setInner);
            }


            //里面放置了N组 特殊情况的要进行 OR的queryStr
            for (Set<String> setInner : setCollection) {
                List<String> list1 = new ArrayList<>();
                for (String wordWithsemantic : setInner) {
                    list1.add("+(" + sematicAndWordWithQueryStrMap.get(wordWithsemantic) + ")");
                    sematicAndWordSet.remove(wordWithsemantic);
                }
                if (list1.size() > 0) {
                    list.add("+(" + list1.stream().collect(Collectors.joining(orOperation)) + ")");
                }

            }


            if (sematicAndWordSet.size() > 0) {
                String[] newOneAttr = new String[sematicAndWordSet.size()];
                int i = 0;
                for (String s : sematicAndWordSet) {
                    if (i < sematicAndWordSet.size()) {
                        newOneAttr[i] = s;
                    }
                    i++;
                }

                List<String> list2 = getOneAttrQueryList(newOneAttr);

                list.addAll(list2);
            }


            if (list.size() > 0) {
                return "+(" + list.stream().collect(Collectors.joining(andOperation)) + ")";
            }


        }

        return "";
    }

    /**
     * 已经排出了特殊情况后的数组 也就是排出了这两种的
     * specialFamily.put("3", "职位;技能");
     * specialFamily.put("13", "城市;区域");
     *
     * @param oneAttr
     * @return
     */
    public static List getOneAttrQueryList(String[] oneAttr) {

        List<String> list = new ArrayList<>();
        String orOperation = " OR ";
        //map的结构 "职位"为相同的语义，销售和 经理分别是词，冒号后面的结果为数组中的下标
        // 1有相同的 {"职位":"销售:1;经理:2"}
        // 2 无相同的 {"职位":"销售:1"，"职级":"经理:2"}
        Map<String, String> map = new HashMap<>();

        if (Objects.nonNull(oneAttr) && oneAttr.length > 0) {
            //用来装拼好的查寻solr的串,用来后面进行取
            String[] queryStrAttr = new String[oneAttr.length];
            for (int i = 0; i < oneAttr.length; i++) {
                //开始直接获取第二个元素，排除0节点这个根节点
                String wordWithsemantic = oneAttr[i];
                String oneQueryStr = wordWithsemantic + "->" + "solr";
                queryStrAttr[i] = oneQueryStr;

                String word = wordWithsemantic.split(":")[0];
                String semantic = wordWithsemantic.split(":")[1];
                if (map.containsKey(semantic)) {
                    word = map.get(semantic) + ";" + word + ":" + i;
                } else {
                    word = word + ":" + i;
                }
                map.put(semantic, word);
            }

            for (Map.Entry<String, String> map1 : map.entrySet()) {
                //销售:1;经理:2  或者 销售:1 这样的值 String类型
                String valueWord = map1.getValue();
                //证明只有一个值
                if (!valueWord.contains(";")) {
                    //获取i值
                    String i = valueWord.split(":")[1];
                    list.add("+(" + queryStrAttr[Integer.parseInt(i)] + ")");
                } else {
                    List<String> listSemanticTheSame = new ArrayList<>();
                    String[] valueWordAttr = valueWord.split(";");
                    for (int i1 = 0; i1 < valueWordAttr.length; i1++) {
                        String i = valueWordAttr[i1].split(":")[1];
                        listSemanticTheSame.add("+(" + queryStrAttr[Integer.parseInt(i)] + ")");
                    }

                    list.add("+(" + listSemanticTheSame.stream().collect(Collectors.joining(orOperation)) + ")");
                }
            }

        }
        return list;
    }

}

